package com.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.domain.UserInfo;
import com.domain.Video;
import com.domain.VideoComment;
import com.dto.PageResult;
import com.exception.ConditionException;
import com.mapper.VideoCommentDao;
import com.mapper.VideoDao;
import com.service.VideoCommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class VideoCommentServiceImpl extends ServiceImpl<VideoCommentDao, VideoComment> implements VideoCommentService {

    @Autowired
    private VideoDao videoDao;

    @Autowired
    private VideoCommentDao videoCommentDao;

    @Autowired
    private UserServiceImpl userServiceImpl;

    public VideoComment getVideoComment(Long videoId) {
        QueryWrapper<VideoComment> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.lambda().eq(VideoComment::getId, videoId);
        VideoComment video = videoCommentDao.selectOne(videoQueryWrapper);
        return video;
    }

    /**
     * 添加视频评论
     */
    public void addVideoComment(VideoComment videoComment, Long userId) {
        Long videoId = videoComment.getVideoId();
        if (videoId == null) {
            throw new ConditionException("参数异常");
        }
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.lambda().eq(Video::getId, videoId);
        Video video = videoDao.selectOne(videoQueryWrapper);
        if (video == null) {
            throw new ConditionException("非法视频");
        }
        videoComment.setUserId(userId);
        videoComment.setCreateTime(new Date());
        videoCommentDao.addVideoComment(videoComment);
    }

    /**
     * 分页查询视频评论
     */
    public PageResult<VideoComment> pageListVideoComments(Integer size, Integer no, Long videoId) {
        QueryWrapper<Video> videoQueryWrapper = new QueryWrapper<>();
        videoQueryWrapper.lambda().eq(Video::getId, videoId);
        Video video = videoDao.selectOne(videoQueryWrapper);
        if (video == null) {
            throw new ConditionException("非法视频");
        }
        //查这条视频的评论总数，如果大于0，才继续下面的操作
        Map<String, Object> params = new HashMap<>();
        params.put("start", (no - 1) * size);
        params.put("limit", size);
        params.put("videoId", videoId);

        //查询这条视频有总共有多少条一级评论
        Integer total = videoCommentDao.pageCountVideoComments(params);

        List<VideoComment> list = new ArrayList<>();
        if (total > 0) {
            //获取所有的一级评论
            list = videoCommentDao.pageListVideoComments(params);
            /*
                如果要在数据库中循环查询每个一级评论下的二级评论，这样会造成多次磁盘IO，效率很低。
                所以在VideoComment类下增加childList属性，记录本评论下的所有二级评论，一次性查出来，避免多次磁盘IO
            */

            //批量查询二级评论
            //parentIdList是所有一级评论的主键id集合
            List<Long> parentIdList = list.stream().map(VideoComment::getId).collect(Collectors.toList());
            //在数据库通过parentIdList查出所有的二级评论
            List<VideoComment> childCommentList = videoCommentDao.batchGetVideoCommentsByRootIds(parentIdList);

            //批量查询评论用户信息
            Set<Long> userIdList = list.stream().map(VideoComment::getUserId).collect(Collectors.toSet());
            Set<Long> replyUserId = childCommentList.stream().map(VideoComment::getReplyUserId).collect(Collectors.toSet());
            //合并成所有的userId合集
            userIdList.addAll(replyUserId);

            //通过总的userId合集查出这些userId对应的用户信息
            List<UserInfo> userInfoList = userServiceImpl.batchGetUserInfoByUserIds(userIdList);
            //key是userId，value是该userId的用户信息
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId, userinfo -> userinfo));

            //遍历一级评论列表
            list.forEach(comment -> {
                Long id = comment.getId();
                //把该一级评论下的二级评论加到childList，再把childList加到一级评论的属性里
                List<VideoComment> childList = new ArrayList<>();
                //遍历二级评论数据列表，如果当前一级评论的主键id等于该二级评论的rootId，说明该二级评论属于该一级评论
                childCommentList.forEach(child -> {
                    if (id.equals(child.getRootId())) {
                        //给该二级评论用户的 userInfo 属性和 replyUserInfo 属性赋值
                        child.setUserInfo(userInfoMap.get(child.getUserId()));
                        child.setReplyUserInfo(userInfoMap.get(child.getReplyUserId()));
                        //把该二级评论的数据加入一级评论的childList中
                        childList.add(child);
                    }
                });
                comment.setChildList(childList);
                comment.setUserInfo(userInfoMap.get(comment.getUserId()));
            });
        }
        return new PageResult<>(total, list);
    }

}
